package com.centersoft.flowable.core.flowableBean;

import cn.hutool.extra.spring.SpringUtil;
import com.centersoft.flowable.core.exception.FlowableRuntimeException;
import com.centersoft.flowable.core.gateway.UserInterface;
import com.centersoft.flowable.core.model.FlowAssigneeModel;
import com.centersoft.flowable.core.model.TaskDefExtension;
import com.centersoft.flowable.core.web.gateway.TaskDefExtensionGateway;
import com.centersoft.flowable.core.dto.TaskDefExtensionRequest;
import com.centersoft.flowable.core.util.FlowableUtils;
import org.flowable.bpmn.model.FlowElement;
import org.flowable.bpmn.model.Process;
import org.flowable.bpmn.model.UserTask;
import org.flowable.common.engine.impl.el.ExpressionManager;
import org.flowable.engine.HistoryService;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.impl.bpmn.behavior.UserTaskActivityBehavior;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.flowable.task.service.TaskService;
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
import org.springframework.util.CollectionUtils;

import java.util.*;

public class ExtUserTaskActivityBehavior extends UserTaskActivityBehavior {

    public ExtUserTaskActivityBehavior(UserTask userTask) {
        super(userTask);
    }

    /**
     * 分配办理人员
     */
    @Override
    protected void handleAssignments(
            TaskService taskService,
            String assignee,
            String owner,
            List<String> candidateUsers,
            List<String> candidateGroups,
            TaskEntity task,
            ExpressionManager expressionManager,
            DelegateExecution execution) {

        Process process = SpringUtil.getBean(RepositoryService.class)
                .getBpmnModel(task.getProcessDefinitionId())
                .getMainProcess();
        FlowElement flowElement = process.getFlowElement(task.getTaskDefinitionKey());
        Boolean isMultiInstance = FlowableUtils.isFlowElementMultiInstance(flowElement);
        if (isMultiInstance) {
            super.handleAssignments(taskService, assignee, owner, candidateUsers, candidateGroups, task, expressionManager, execution);
            return;
        }
        TaskDefExtensionRequest taskDefExtensionRequest = new TaskDefExtensionRequest();
        taskDefExtensionRequest.setTaskDefId(task.getTaskDefinitionKey());
        taskDefExtensionRequest.setProcessDefId(process.getId());
        List<TaskDefExtension> list = SpringUtil.getBean(TaskDefExtensionGateway.class).findList(taskDefExtensionRequest);
        HashSet<String> candidateUserIds = new HashSet<>();

        UserInterface userInterface = SpringUtil.getBean(UserInterface.class);

        if (list.size() > 0) {
            TaskDefExtension taskDefExtension = list.get(0);
            // 获取流程代办用户id
            List<FlowAssigneeModel> assigneeList = SpringUtil.getBean(TaskDefExtensionGateway.class).getFlowAssigneeList(taskDefExtension.getId());


            List<FlowAssigneeModel> otherAssigneeList = new ArrayList<>();


            for (FlowAssigneeModel flowAssignee : assigneeList) {
                String type = flowAssignee.getType();
                switch (type) {
                    case FlowAssigneeModel.TYPE_USER:
                    case FlowAssigneeModel.TYPE_EMPLOYEE:
                        candidateUserIds.addAll(flowAssignee.getValues());
                        break;
                    case FlowAssigneeModel.TYPE_PREVIOUS_EXECUTOR:
                        HistoricTaskInstance lastHisTask = SpringUtil.getBean(HistoryService.class)
                                .createHistoricTaskInstanceQuery()
                                .processInstanceId(task.getProcessInstanceId())
                                // .finished()
                                .includeProcessVariables()
                                .orderByHistoricTaskInstanceEndTime()
                                .desc()
                                .list()
                                .get(0);
                        candidateUserIds.add(lastHisTask.getAssignee());
                        break;
                    default:
                        otherAssigneeList.add(flowAssignee);
                        break;
                }
            }
            if (!otherAssigneeList.isEmpty()) {
                Set<String> userByAssigneeTypeVo = userInterface.getUserByAssigneeTypeVo(otherAssigneeList);
                if (!CollectionUtils.isEmpty(userByAssigneeTypeVo)) {
                    candidateUserIds.addAll(userByAssigneeTypeVo);
                }
            }
        }

        if (CollectionUtils.isEmpty(candidateUserIds)) {
            throw new FlowableRuntimeException("未匹配到审核人员");
        }
        List<String> candidateIds = new ArrayList<>(candidateUserIds);
        // 此处可以根据业务逻辑自定义
        if (candidateIds.size() == 0) {
            super.handleAssignments(taskService, null, owner, new ArrayList<>(), new ArrayList<>(), task, expressionManager, execution);
        } else if (candidateIds.size() == 1) {
            super.handleAssignments(taskService, candidateIds.get(0), owner, new ArrayList<>(), new ArrayList<>(), task, expressionManager, execution);
        } else {
            super.handleAssignments(taskService, null, owner, candidateIds, null, task, expressionManager, execution);
        }
    }
}
